package cn.com.dhcc.app.pub.core.consts;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.ListUtils;

import cn.com.dhcc.turbo.entity.exch.CrossNetTmpCmData;
import cn.com.dhcc.turbo.entity.exch.CrossNetTmpFileData;
import cn.com.dhcc.turbo.entity.exch.RecvCmData;
import cn.com.dhcc.turbo.entity.exch.RecvFileData;
import cn.com.dhcc.turbo.entity.exch.SendCmData;
import cn.com.dhcc.turbo.entity.exch.SendFileData;

/**
 * 数据交换内存,用来标记优先级改变的记录
 * 存储数据交换
 * 
 * @日期 2014-12-8 下午5:06:40
 * @作者  高强
 */
public class ExchDataMemory {
	
	/**
	 * 触发点 
	 */
	public static enum Point {
		LOCAL_STORE("1", "本地存储"), 
		OUT_GAP_STORE("2", "外网网闸存储"), 
		INNER_GAP_STORE("3", "外网网闸存储"), 
		REMOTE_STORE("4", "远程存储"); 
		private String type;
		private String desc;

		private Point(String type, String desc) {
			this.type = type;
			this.desc = desc;
		}

		public String getType() {
			return type;
		}

		public String getDesc() {
			return desc;
		}

		public void setType(String type) {
			this.type = type;
		}

		public void setDesc(String desc) {
			this.desc = desc;
		}

		public String value() {
			return this.type;
		}

		@Override
		public String toString() {
			return type;
		}
    }
	
	
	/**
	 * 触发类型
	 */
	public static enum PointType {
		CM_DATA("1", "结构化数据"), 
		FILE_DATA("2", "非结构化数据");
		private String type;
		private String desc;

		private PointType(String type, String desc) {
			this.type = type;
			this.desc = desc;
		}

		public String getType() {
			return type;
		}

		public String getDesc() {
			return desc;
		}

		public void setType(String type) {
			this.type = type;
		}

		public void setDesc(String desc) {
			this.desc = desc;
		}

		public String value() {
			return this.type;
		}

		@Override
		public String toString() {
			return type;
		}
    }
	
	

	public static Map<String,Map<String,Map<String,List<String>>>> memory=new HashMap<String,Map<String,Map<String,List<String>>>>();
	
	/**
	 * 删除id
	 * @param dataMap
	 * @param id
	 */
	private static void clearId(Map<String,List<String>> dataMap,String id){
		if (dataMap==null || dataMap.isEmpty()) {
			return;
		}
		Set<String> keys=dataMap.keySet();
		for (String key : keys) {
			List<String> list=dataMap.get(key);
			if (list.contains(id)) {
				list.remove(id);
			}
		}
	}
	/**
	 * 清除对应的数据
	 * @param point
	 * @param type
	 * @param priority
	 */
	public static synchronized  void clear(ExchDataMemory.Point point,ExchDataMemory.PointType type,List<?> list){
		Map<String,Map<String,List<String>>> typeMap=memory.get(point.value());
		if (typeMap==null || typeMap.isEmpty()) {
			return;
		}
		Map<String,List<String>> dataMap=typeMap.get(type.value());
		if (dataMap==null || dataMap.isEmpty()) {
			return;
		}
		
		for (Object obj : list) {
			if (obj instanceof SendCmData) {
				SendCmData sendCmData=(SendCmData)obj;
				clearId(dataMap, sendCmData.getId());
			}else if(obj instanceof SendFileData){
				SendFileData sendFileData=(SendFileData)obj;
				clearId(dataMap, sendFileData.getOrderId());
			}else if(obj instanceof RecvCmData){
				RecvCmData recvCmData=(RecvCmData)obj;
				clearId(dataMap, recvCmData.getId());
			}else if(obj instanceof RecvFileData){
				RecvFileData recvFileData=(RecvFileData)obj;
				clearId(dataMap, recvFileData.getOrderId());
			}else if(obj instanceof CrossNetTmpCmData){
				CrossNetTmpCmData crossNetTmpCmData=(CrossNetTmpCmData)obj;
				clearId(dataMap, crossNetTmpCmData.getId());
			}else if(obj instanceof CrossNetTmpFileData){
				CrossNetTmpFileData crossNetTmpFileData=(CrossNetTmpFileData)obj;
				clearId(dataMap, crossNetTmpFileData.getOrderId());
			}
		}
		
	}
	
	/**
	 * 
	 * @param point 触发点 
	 * @param type  触发类型
	 * @param priority 优先级
	 * @param id  主键id
	 * @return
	 */
	public static synchronized Map<String,Map<String,Map<String,List<String>>>> add(ExchDataMemory.Point point,ExchDataMemory.PointType type,AppConst.Priority priority,String id){
		Map<String,Map<String,List<String>>> typeMap=memory.get(point.value());
		if (typeMap==null) {
			typeMap=new HashMap<String, Map<String,List<String>>>();
		}
		Map<String,List<String>> dataMap=typeMap.get(type.value());
		if (dataMap==null) {
			dataMap=new HashMap<String, List<String>>();
		}
		List<String> list=dataMap.get(priority.value());
		if (list==null) {
			list=new ArrayList<String>();
		}
		if (!list.contains(id)) {
			list.add(id);
		}
		
		dataMap.put(priority.value(),list);
	    typeMap.put(type.value(), dataMap);
	    memory.put(point.value(), typeMap);
		
		return memory;
	}
	/**
	 * 
	 * @param point 触发点 
	 * @param type  触发类型
	 * @param priority 优先级
	 * @param idList  移除主键id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static synchronized Map<String,Map<String,Map<String,List<String>>>> remove(ExchDataMemory.Point point,ExchDataMemory.PointType type,AppConst.Priority priority,List<String> idList){
		Map<String,Map<String,List<String>>> typeMap=memory.get(point.value());
		if (typeMap==null || typeMap.isEmpty()) {
			return memory;
		}
		Map<String,List<String>> dataMap=typeMap.get(type.value());
		if (dataMap==null || dataMap.isEmpty()) {
			return memory;
		}
		
		List<String> list=dataMap.get(priority.value());
		if (list==null || list.isEmpty()) {
			return memory;
		}
		list= ListUtils.subtract(list, idList);
		dataMap.put(priority.value(), ListUtils.subtract(list, idList));
		return memory;
	}
	
	/**
	 * 判断某种类型，某种数据，某种权限是否在内存中存在
	 * @param point
	 * @param type
	 * @param priority 比 priority优先级高的
	 * @return
	 */
	public static synchronized boolean existsHigherPriority(ExchDataMemory.Point point,ExchDataMemory.PointType type,AppConst.Priority priority){
		Map<String,Map<String,List<String>>> typeMap=memory.get(point.value());
		if (typeMap==null || typeMap.isEmpty()) {
			return false;
		}
		Map<String,List<String>> dataMap=typeMap.get(type.value());
		if (dataMap==null || dataMap.isEmpty()) {
			return false;
		}
		List<String> list=null;
		//如果最高的优先级小于priority
		if (Integer.parseInt(AppConst.Priority.FAST.value())<Integer.parseInt(priority.value())) {
			list=dataMap.get(AppConst.Priority.FAST.value());
		}else if (Integer.parseInt(AppConst.Priority.NORMAL.value())<Integer.parseInt(priority.value())){
			list=dataMap.get(AppConst.Priority.NORMAL.value());
		}else{
			return false;
		}
		if (list==null || list.isEmpty()) {
			return false;
		}else{
			return true;
		}
	}
	
//	public static void main(String[] args) {
		/*List<String> list=new ArrayList<String>();
		list.add("123");
		System.out.println(ExchDataMemory.add(ExchDataMemory.Point.LOCAL_STORE, ExchDataMemory.PointType.CM_DATA, AppConst.Priority.FAST, "123"));
		System.out.println(ExchDataMemory.add(ExchDataMemory.Point.OUT_GAP_STORE, ExchDataMemory.PointType.FILE_DATA, AppConst.Priority.NORMAL, "456"));
		System.out.println(ExchDataMemory.remove(ExchDataMemory.Point.LOCAL_STORE, ExchDataMemory.PointType.CM_DATA, AppConst.Priority.FAST, list));
	*/
		
		/*Map<String,List<String>> dataMap=new HashMap<String, List<String>>();
		List<String> list=new ArrayList<String>();
		list.add("123");
		list.add("456");
		List<String> list1=new ArrayList<String>();
		list1.add("789");
		dataMap.put("1", list);
		dataMap.put("2", list1);
		System.out.println(dataMap);
		ExchDataMemory.clearId(dataMap, "123");
		System.out.println(dataMap);*/
//		System.out.println(ExchDataMemory.add(ExchDataMemory.Point.LOCAL_STORE, ExchDataMemory.PointType.CM_DATA, AppConst.Priority.FAST, "123"));
//		System.out.println(ExchDataMemory.add(ExchDataMemory.Point.OUT_GAP_STORE, ExchDataMemory.PointType.FILE_DATA, AppConst.Priority.NORMAL, "456"));
//		List list=new ArrayList();
//		SendCmData c=new SendCmData();
//		c.setId("123");
//		list.add(c);
//		
//		SendFileData c1=new SendFileData();
//		c1.setOrderId("456");
//		list.add(c1);
//		//clear(ExchDataMemory.Point.LOCAL_STORE, ExchDataMemory.PointType.CM_DATA, list);
//		System.out.println(ExchDataMemory.existsHigherPriority(ExchDataMemory.Point.LOCAL_STORE, ExchDataMemory.PointType.CM_DATA, AppConst.Priority.SLOW));
//	}
}
